package cn.jingyuan.owl.utils.core.text;

import cn.jingyuan.owl.utils.core.CharUtils;
import cn.jingyuan.owl.utils.core.HexUtils;
import cn.jingyuan.owl.utils.core.StringUtils;

/**
 * 提供 Unicode 字符串和普通字符串之间的转换
 */
public class UnicodeUtils {

    /**
     * Unicode 字符串转为普通字符串<br>
     * Unicode 字符串的表现方式为：\\uXXXX
     *
     * @param unicode Unicode 字符串
     *
     * @return 普通字符串
     */
    public static String toString(String unicode) {
        if (StringUtils.isBlank(unicode)) {
            return unicode;
        }

        final int len = unicode.length();
        StringsBuilder sb = StringsBuilder.create(len);
        int i;
        int pos = 0;
        while ((i = StringUtils.indexOfIgnoreCase(unicode, "\\u", pos)) != -1) {
            sb.append(unicode, pos, i);// 写入 Unicode 符之前的部分
            pos = i;
            if (i + 5 < len) {
                char c;
                try {
                    c = (char) Integer.parseInt(unicode.substring(i + 2, i + 6), 16);
                    sb.append(c);
                    pos = i + 6;// 跳过整个 Unicode 符
                } catch (NumberFormatException e) {
                    // 非法 Unicode 符，跳过
                    sb.append(unicode, pos, i + 2);// 写入"\\u"
                    pos = i + 2;
                }
            } else {
                // 非 Unicode 符，结束
                pos = i;
                break;
            }
        }

        if (pos < len) {
            sb.append(unicode, pos, len);
        }
        return sb.toString();
    }

    /**
     * 字符串编码为 Unicode 形式
     *
     * @param string 被编码的字符串
     *
     * @return Unicode 字符串
     */
    public static String toUnicode(String string) {
        return toUnicode(string, true);
    }

    /**
     * 字符串编码为 Unicode 形式
     *
     * @param string 被编码的字符串
     * @param isSkipAscii 是否跳过 ASCII 字符（只跳过可见字符）
     *
     * @return Unicode 字符串
     */
    public static String toUnicode(String string, boolean isSkipAscii) {
        if (StringUtils.isEmpty(string)) {
            return string;
        }

        final int len = string.length();
        final StringsBuilder unicode = StringsBuilder.create(string.length() * 6);
        char c;
        for (int i = 0; i < len; i++) {
            c = string.charAt(i);
            if (isSkipAscii && CharUtils.isAsciiPrintable(c)) {
                unicode.append(c);
            } else {
                unicode.append(HexUtils.toUnicodeHex(c));
            }
        }
        return unicode.toString();
    }

}
